/* 482 */
/***/
import * as Cesium from '@cesiumjs';
import {
  G3xObjBase
} from "@g3xbase"
import {
  G3xPolygon
} from "@g3vObjects"
import * as g3xUtils from "@g3x/utils";
import * as g3vUtils from "@g3v/utils";
import {
  autorun,
  reaction,
  intercept,
  extendObservable,
  computed
} from 'mobx';



function isClockwise(poly) {
  var sum = 0;
  for (var i = 0; i < poly.length / 2 - 1; i++) {
    sum += (poly[2 * (i + 1) + 0] - poly[2 * i + 0]) * (poly[2 * (i + 1) + 1] + poly[2 * i + 1]);
  }
  return sum > 0;
}

var temp = void 0;

function swap(array, i, j) {
  temp = array[i];
  array[i] = array[j];
  array[j] = temp;
}

function reversePositions(positions) {
  var pl = positions.length / 2;
  for (var i = 0; i < pl / 2; ++i) {
    swap(positions, i * 2, (pl - i - 1) * 2);
    swap(positions, i * 2 + 1, (pl - i - 1) * 2 + 1);
  }
}

/**
 * 地形限制(地形剖切)
 * @memberof SceneTree
 * @extends XbsjBase
 */
class Restrict extends G3xObjBase {

  constructor(viewer, options) {

    super();

    const _this = this;
    const {disposers} = this;

    _this._viewer = viewer;

    _this._polygon = new G3xPolygon(viewer);
    _this._polygon.color = [1, 1, 0, 0];

    disposers.push(function() {
      return _this._polygon.destroy();
    });

    disposers.push(g3xUtils.track(_this._polygon, 'positions', _this, 'positions'));
    _this.disposers.push(g3xUtils.track(_this._polygon, 'height', _this, 'height'));

    _this.disposers.push((0, _registerInteractionProperty.registerPolygonCreating)(_this._earth, _this, {
      polygonPointAddingProperty: 'creating'
    }));

    _this.disposers.push((0, _registerInteractionProperty.registerPolygonEditing)(_this._earth, _this, {
      polygonEditingProperty: 'editing'
    }));

    // 编辑模式下自动关闭，否则会造成闪烁
    _this.disposers.push((0, _mobx.reaction)(function() {
      return {
        creating: _this.creating,
        editing: _this.editing
      };
    }, function() {
      if (_this.creating || _this.editing) {
        _this.enabled = false;
      }
    }));

    _this.disposers.push((0, _mobx.autorun)(function() {
      _this._polygon.show = _this.showHelper;
    }));

    _this._alwayTopImageryLayer = undefined;

    var scene = _this._earth.czm.scene;
    _this.disposers.push(reaction(function() {
      return {
        positions: [].concat((0, _toConsumableArray3.default)(_this.positions)),
        innerDiscard: _this.innerDiscard,
        enabled: _this.enabled
      };
    }, function() {
      scene.xbsjRestrictImagery = _this.enabled;

      if (_this._alwayTopImageryLayer) {
        scene.imageryLayers.remove(_this._alwayTopImageryLayer);
        _this._alwayTopImageryLayer = undefined;
      }

      // if (_this.enabled) {
      //   _this._alwayTopImageryLayer = new Cesium.ImageryLayer(new Cesium.RestrictImageryProvider({
      //     positions: _this.positions,
      //     innerDiscard: _this.innerDiscard
      //   }));
      //   _this._alwayTopImageryLayer.xbsjZIndex = _maxSafeInteger2.default;
      //   scene.imageryLayers.add(_this._alwayTopImageryLayer);
      // }

      _this._earth._xbsjImageryZIndexDirty = true;
    }));

    // // globe.depthTestAgainstTerrain = true;
    // const globe = this._earth.czm.scene.globe;
    // globe.clippingPlanes = new Cesium.ClippingPlaneCollection({
    //     modelMatrix : Cesium.Matrix4.clone(Cesium.Matrix4.IDENTITY),
    //     planes : [
    //         // new Cesium.ClippingPlane(new Cesium.Cartesian3( 0.0, -1.0, 0.0), -700.0)
    //     ],
    //     edgeWidth: this.edgeWidth,
    //     edgeColor: new Cesium.Color(...this.edgeColor),
    //     enabled : this.enabled,
    //     unionClippingRegions: false,
    // });

    // this.disposers.push(autorun(() => {
    //     globe.clippingPlanes.enabled = this.enabled;
    //     globe.clippingPlanes.edgeColor.red = this.edgeColor[0];
    //     globe.clippingPlanes.edgeColor.green = this.edgeColor[1];
    //     globe.clippingPlanes.edgeColor.blue = this.edgeColor[2];
    //     globe.clippingPlanes.edgeColor.alpha = this.edgeColor[3];

    //     globe.clippingPlanes.edgeWidth = this.edgeWidth;
    //     // globe.clippingPlanes.unionClippingRegions = this.unionClippingRegions;
    // }));

    // const scratchStart = new Cesium.Cartesian3();
    // const scratchEnd = new Cesium.Cartesian3();
    // const scratchCartesian = new Cesium.Cartesian3();
    // const scratchCartesian2 = new Cesium.Cartesian3();
    // const scratchCartesian3 = new Cesium.Cartesian3();
    // const scratchCartesian4 = new Cesium.Cartesian3();
    // const scratchCartesian5 = new Cesium.Cartesian3();
    // const scratchPlane = new Cesium.Plane(new Cesium.Cartesian3(0, 0, 1), 0.0);
    // this.disposers.push(autorun(() => {
    //     const planes = [];
    //     const l = globe.clippingPlanes.length;
    //     for (let i=0; i<l; ++i) {
    //         planes.push(globe.clippingPlanes.get(i));
    //     }
    //     globe.clippingPlanes.removeAll();

    //     if (this.positions.length >= 2*3) {
    //         let positions = this.positions;
    //         // 逆时针且union为true时，抛弃外围；顺时针且union为false时，挖坑
    //         if (this.innerDiscard) { // 挖坑
    //             globe.clippingPlanes.unionClippingRegions = false;
    //             if (!isClockwise(positions)) {
    //                 positions = [...positions];
    //                 reversePositions(positions);
    //             }
    //         } else {
    //             globe.clippingPlanes.unionClippingRegions = true;
    //             if (isClockwise(positions)) {
    //                 positions = [...positions];
    //                 reversePositions(positions);
    //             }
    //         }

    //         const sum = [0, 0, 0];

    //         const l = positions.length / 2;

    //         for (let i=0; i<l; ++i) {
    //             sum[0] += positions[i*2];
    //             sum[1] += positions[i*2 + 1];
    //         }
    //         sum[0] /= l;
    //         sum[1] /= l;
    //         sum[2] = this.height;

    //         const center = Cesium.Cartesian3.fromRadians(sum[0], sum[1], sum[2], undefined, scratchCartesian);
    //         Cesium.Matrix4.fromTranslation(center, globe.clippingPlanes.modelMatrix);
    //         const up = Cesium.Cartesian3.normalize(center, scratchCartesian2);

    //         planes.length = l;
    //         for (let i=0; i<l; ++i) {
    //             const start = Cesium.Cartesian3.fromRadians(positions[i*2], positions[i*2+1], this.height, undefined, scratchStart);
    //             let ii = (i + 1) % l;
    //             const end = Cesium.Cartesian3.fromRadians(positions[ii*2], positions[ii*2+1], this.height, undefined, scratchEnd);
    //             if (Cesium.Cartesian3.distanceSquared(start, end) > 0.01) {
    //                 const dir = Cesium.Cartesian3.subtract(end, start, scratchCartesian3);
    //                 Cesium.Cartesian3.normalize(dir, dir);
    //                 const normal = Cesium.Cartesian3.cross(up, dir, scratchCartesian4);
    //                 Cesium.Cartesian3.normalize(normal, normal);
    //                 const point = Cesium.Cartesian3.subtract(start, center, scratchCartesian5);
    //                 const plane = Cesium.Plane.fromPointNormal(point, normal, scratchPlane);
    //                 planes[i] = Cesium.ClippingPlane.fromPlane(plane, planes[i]);
    //             }
    //         }
    //         planes.forEach(e => globe.clippingPlanes.add(e));
    //     }
    // }));
  }
}


g3xUtils.g3x_defineClassProperties(Restrict, [{
  key: 'flyTo',
  value: function flyTo() {
    var l = this.positions.length / 2;
    var center = [0, 0, 0];
    var min = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY];
    var max = [Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY];
    for (var i = 0; i < l; ++i) {
      var p0 = this.positions[i * 2 + 0];
      var p1 = this.positions[i * 2 + 1];
      center[0] += p0;
      center[1] += p1;
      min[0] = min[0] < p0 ? min[0] : p0;
      min[1] = min[1] < p1 ? min[1] : p1;
      max[0] = max[0] > p0 ? max[0] : p0;
      max[1] = max[1] > p1 ? max[1] : p1;
    }

    center[0] /= l;
    center[1] /= l;
    center[2] = this.height;

    var d = _Math2.default.geoDistance(min, max);

    this._earth.camera.flyTo(center, d);
  }
}, {
  key: 'destroy',
  value: function destroy() {
    return (0, _get3.default)(Restrict.prototype.__proto__ || (0, _getPrototypeOf2.default)(Restrict
      .prototype), 'destroy', this).call(this);
  }
}]);

Restrict.defaultOptions = {
  /**
   * 计算网格所构成的多边形坐标位置，形如： [经度, 纬度, 经度, 纬度, ...]
   * @description 注意：必须是偶数个元素！
   * @instance
   * @memberof TerrainEffect.Restrict
   * @type {number[]}
   * @default []
   */
  positions: [],
  /**
   * 多边形区域高度
   * @instance
   * @memberof TerrainEffect.Restrict
   * @type {number}
   * @default 0.0
   */
  height: 0.0,
  /**
   * 是否开启
   * @instance
   * @memberof TerrainEffect.Restrict
   * @type {boolean}
   * @default false
   */
  enabled: false,
  /**
   * 是否显示辅助线框
   * @type {boolean}
   * @instance
   * @default false
   * @memberof TerrainEffect.Restrict
   */
  showHelper: false,
  /**
   * 边缘线宽度
   * @type {number}
   * @instance
   * @default 1
   * @memberof TerrainEffect.Restrict
   */
  edgeWidth: 1,
  /**
   * 等高线颜色
   * @type {number[]}
   * @default [1, 1, 1, 1]
   * @instance
   * @memberof TerrainEffect.Restrict
   */
  edgeColor: [1, 1, 1, 1],
  // unionClippingRegions: false,
  /**
   * 是否裁切多边形内部（挖坑），若为false，则裁切多边形外部区域。
   * @type {boolean}
   * @instance
   * @default false
   * @memberof TerrainEffect.Restrict
   */
  innerDiscard: false
};

export {Restrict};
export default Restrict;
